import type { NextPage } from "next";
import { useCallback, useEffect, useRef, useState } from "react";
import { init } from "../src/meta/script";
import styled, { css } from "styled-components";
import Banner from "../src/components/Home/Banner";
import { loadInfoControls } from "../src/meta/helper/loadInfoControls";
import Navigate from "../src/components/Nav";

const Home: NextPage = () => {
    const canvasRef = useRef<HTMLCanvasElement>(null);
    //是否进入过canvas
    const [enter, setEnter] = useState(false);
    //是否小窗模式显示canvas
    const [smallWindow, setSmallWindow] = useState(false);
    //小窗canvas的缩放动画结束
    const [smallWindowAnimation, setSmallWindowAnimation] = useState(false);
    //THREE模型/纹理等加载进度信息
    const [loadInfo, setLoadInfo] = useState({
        info: loadInfoControls.info,
        complete: loadInfoControls.complete,
    });
    //键盘时间监听 用以取消监听 防止在浏览网页时继续监听按键 造成意外影响
    const keyListenRef = useRef<ReturnType<typeof init.enter>>();

    useEffect(() => {
        /**
         * 防止缩小时被鼠标触碰进入hover样式影响缩小动画在缩小完成后再加入hover样式
         */
        setTimeout(() => {
            setSmallWindowAnimation(smallWindow);
        }, 300);
    }, [smallWindow]);

    useEffect(() => {
        if (enter) {
            //解除小窗模式并且小窗模式动画完毕再锁定鼠标
            if (!smallWindow && !smallWindowAnimation) {
                console.time();
                const { removeListener, mouseControls } = init.enter();
                keyListenRef.current = { removeListener, mouseControls };
                console.timeEnd();

                mouseControls.unlockCallback(() => {
                    console.log("EXIT ");
                    setSmallWindow(true);
                });
            }
        }

        return () => {
            keyListenRef.current?.removeListener();
        };
    }, [enter, smallWindow, smallWindowAnimation, setSmallWindow]);

    useEffect(() => {
        if (!canvasRef.current) throw Error("获取canvas失败");
        loadInfoControls.onChange(() => {
            setLoadInfo({
                info: loadInfoControls.info,
                complete: loadInfoControls.complete,
            });
        });
        init({
            antialias: true,
            canvas: canvasRef.current!,
        });
    }, []);

    const enterMeta = useCallback(() => {
        console.log("enter");

        if (smallWindow) {
            //从小窗进入
            setSmallWindow(false);
        } else setEnter(true);
    }, [smallWindow]);

    return (
        <>
            <Navigate />
            <Container>
                <Banner loadInfo={loadInfo} enterMeta={enterMeta} />
                <Banner loadInfo={loadInfo} enterMeta={enterMeta} />
                <CanvasBox
                    onClick={enterMeta}
                    showCanvas={enter}
                    canvasSmallWindow={smallWindow}
                    smallWindowAnimation={smallWindowAnimation}
                >
                    <canvas ref={canvasRef}></canvas>
                </CanvasBox>
            </Container>
        </>
    );
};

export default Home;

const CanvasBox = styled.div<{ showCanvas: boolean; canvasSmallWindow: boolean; smallWindowAnimation: boolean }>`
    --color: #206a11;
    position: fixed;
    width: 100vw;
    height: 100vh;
    right: 0;
    bottom: 0;
    border: 0vw solid var(--color);
    transition: all 0.3s linear;
    z-index: ${({ showCanvas }) => (showCanvas ? 1000 : -1)};
    opacity: ${({ showCanvas }) => +showCanvas};
    cursor: pointer;
    canvas {
        width: 100% !important;
        height: 100% !important;
    }

    ${({ canvasSmallWindow, smallWindowAnimation }) =>
        canvasSmallWindow &&
        css`
            width: 15vw;
            height: 15vh;
            right: 10vw;
            bottom: 10vh;
            border-width: 0.7vw;
            background: var(--color);
            border-radius: 0.7vw;
            box-shadow: 1vw 1vh 4vw 0px var(--color);
            canvas {
                border-radius: 0.7vw;
            }
            //防止缩小时被鼠标触碰进入hover样式影响缩小动画在缩小完成后再加入hover样式
            ${smallWindowAnimation &&
            `
                :hover {
                    width: 35vw;
                    height: 35vh;
                }
            `}
        `}
`;

const Container = styled.div``;
